<template lang="">
  <div class="play_container">
    <video ref="videoPlayer" class="video-js vjs-default-skin vjs-big-play-centered video_container"></video>
  </div>
</template>
<script>
import "video.js/dist/video-js.css";
import "videojs-markers/dist/videojs.markers.css";
import videojs from "video.js";
import "videojs-markers";
import "videojs-markers/dist/videojs.markers.css";
// 自定义控件
const customControl = ["提问时间点", "互动时间点", "练习时间点", "专注时间点", "散漫时间点"];

const enumPointType = {
  QUESTION: "提问时间点",
  INTERACTION: "互动时间点",
  PRACTICE: "练习时间点",
  ATTENTION: "专注时间点",
  RAMBLING: "散漫时间点"
};

let playCom;
let fullCom;

export default {
  data() {
    return {
      player: null,
      totalTime: 0, // 总时长
      currentTime: 0, // 当前时间
      currentPoint: "", // 当前的点
      isSame: false, // 是否为相同的点
      isPlay: false, // 当前是否在播放
      isFull: false // 是否全屏
    };
  },

  computed: {
    formatTime() {
      return (time) => {
        // 将总时间转换为整数秒数
        const totalSeconds = Math.floor(time);

        // 计算小时、分钟和秒数
        const hours = Math.floor(totalSeconds / 3600);
        const minutes = Math.floor((totalSeconds % 3600) / 60);
        const seconds = totalSeconds % 60;

        // 格式化为 "00:00:00" 形式
        const formattedTime = ("0" + hours).slice(-2) + ":" + ("0" + minutes).slice(-2) + ":" + ("0" + seconds).slice(-2);

        return formattedTime;
      };
    }
  },
  methods: {
    // 初始化播放器
    init() {
      let host_addr = sessionStorage.getItem("host_addr");
      const options = {
        autoplay: true, // 自动播放
        language: "zh-CN",
        controls: true, // 控制条
        preload: "auto", // 自动加载
        errorDisplay: true, // 错误展示
        userActions: {
          hotkeys: true // 是否支持热键
        },
        notSupportedMessage: "此视频暂无法播放，请稍后再试",
        sources: [
          {
            src: video_url,
            type: "video/mp4"
          }
        ],
        controlBar: {
          /* 设置控制条里面组件的相关属性及显示与否  */
          remainingTimeDisplay: false,

          children: [
            { name: "progressControl" },
            {
              name: "volumePanel", // 音量控制
              inline: false // 不使用水平方式
            }
          ]
        }
      };
      this.player = videojs(this.$refs.videoPlayer, options, () => {
        videojs.log(`Your player is ready!`);
        // 打点
        this.markers();

        // 获取视频总时间
        this.getVideoDuration();

        // 自定义控件
        this.initControl();
      });

      this.player.on("timeupdate", (e) => {
        // 计算当前时间并显示
        const currenTime = Math.floor(e.target.player.currentTime());
        this.currentTime = this.formatTime(currenTime);
        const pDom = document.querySelector(".vjs-progress-text");
        const cDom = pDom.querySelector(".vjs-control-text");

        cDom.innerText = `${this.currentTime} / ${this.totalTime}`;
      });

      this.player.on("play", () => {
        this.isPlay = true;
        this.formatText();
      });

      this.player.on("pause", () => {
        this.isPlay = false;
        this.formatText();
      });

      this.player.on("end", () => {
        this.isPlay = false;
        this.formatText();
      });

      this.player.on("fullscreenchange", (e, a) => {
        console.info(e, a);
        this.isFull = !this.isFull;
        this.formatFull();
      });
    },

    // 显示打点
    markers() {
      this.player.markers({
        markerStyle: {
          // 标记点样式
          width: "0.7em",
          height: "0.7em",
          bottom: "-0.20em",
          "border-radius": "50%",
          "background-color": "red",
          position: "absolute"
        },

        //鼠标移入标记点的提示
        markerTip: {
          display: true, // 是否显示
          /*
            用于动态构建标记提示文本的回调函数。
            只需返回一个字符串，参数标记是传递给插件的标记对象
          */
          text: function (marker) {
            return marker.text;
          }
        },

        // 点
        markers: []
      });
    },

    // 处理视频点的回调
    handleControl(type) {
      let markerOption = [];

      switch (type) {
        case enumPointType.QUESTION:
          markerOption = [
            {
              time: 20,
              text: "提问点1",
              class: "red"
            },
            {
              time: 40,
              text: "提问点2",
              class: "green"
            },
            {
              time: 60,
              text: "提问点3",
              class: "yellow"
            },
            {
              time: 80,
              text: "提问点4"
            }
          ];
          break;
        case enumPointType.INTERACTION:
          markerOption = [
            {
              time: 5,
              text: "互动1",
              class: "red"
            },
            {
              time: 20,
              text: "互动2",
              class: "green"
            },
            {
              time: 98,
              text: "互动3",
              class: "yellow"
            },
            {
              time: 105,
              text: "互动4"
            }
          ];
          break;
        case enumPointType.PRACTICE:
          markerOption = [
            {
              time: 35,
              text: "练习1",
              class: "red"
            },
            {
              time: 55,
              text: "练习2",
              class: "green"
            },
            {
              time: 65,
              text: "练习3",
              class: "yellow"
            },
            {
              time: 95,
              text: "练习4"
            }
          ];
          break;
        case enumPointType.ATTENTION:
          markerOption = [
            {
              time: 10,
              text: "专注点1",
              class: "red"
            },
            {
              time: 13,
              text: "专注点2",
              class: "green"
            },
            {
              time: 35,
              text: "专注点3",
              class: "yellow"
            },
            {
              time: 59,
              text: "专注点4"
            }
          ];
          break;
        case enumPointType.RAMBLING:
          markerOption = [
            {
              time: 35,
              text: "散漫1",
              class: "red"
            },
            {
              time: 89,
              text: "散漫2",
              class: "green"
            },
            {
              time: 65,
              text: "散漫3",
              class: "yellow"
            },
            {
              time: 46,
              text: "散漫4"
            }
          ];
          break;
      }
      this.player.markers.reset(markerOption);

      if (this.currentPoint === type && !this.isSame) {
        this.player.markers.reset([]);
        this.isSame = true;
      } else {
        this.isSame = false;
      }
      this.currentPoint = type;
    },

    // 初始化自定义控件
    initControl() {
      this.initPlayBtnControl();
      this.initFullScreenControl();
      // 自定义进度时间控件
      this.player.getChild("ControlBar").addChild("button", {
        controlText: `${this.currentTime} / ${this.totalTime}`,
        className: "vjs-visible-text vjs-progress-text"
      });

      customControl.forEach((item) => {
        this.player.getChild("ControlBar").addChild("button", {
          controlText: item,
          className: "vjs-visible-text vjs-custom-btn",
          clickHandler: () => {
            this.handleControl(item);
          }
        });
      });
    },

    // 暂停播放控件
    initPlayBtnControl() {
      // 自定义播放按钮
      const baseComponent = videojs.getComponent("Component");

      const myComponent = videojs.extend(baseComponent, {
        constructor: function (player, options) {
          baseComponent.apply(this, arguments);
          this.on("click", this.clickBtn);
        },
        createEl: function () {
          playCom = videojs.dom.createEl("div", {
            // Prefixing classes of elements within a player with "vjs-"
            // is a convention used in Video.js.
            // 给元素加vjs-开头的样式名，是videojs内置样式约定俗成的做法
            className: "vjs-my-components",
            innerHTML: `<span>播放</span>`
          });

          return playCom;
        },
        clickBtn: this.handleClickBtn
      });
      videojs.registerComponent("myComponent", myComponent);

      // 找到 controlBar 节点，添加控件
      this.player.getChild("controlBar").addChild("myComponent");
    },

    // 全屏控件
    initFullScreenControl() {
      // 自定义播放按钮
      const baseComponent = videojs.getComponent("Component");

      const fullComponent = videojs.extend(baseComponent, {
        constructor: function (player, options) {
          baseComponent.apply(this, arguments);
          this.on("click", this.clickBtn);
        },
        createEl: function () {
          fullCom = videojs.dom.createEl("div", {
            // Prefixing classes of elements within a player with "vjs-"
            // is a convention used in Video.js.
            // 给元素加vjs-开头的样式名，是videojs内置样式约定俗成的做法
            className: "vjs-full-components",
            innerHTML: `<span>全屏</span>`
          });

          return fullCom;
        },
        clickBtn: this.handleClickFull
      });
      videojs.registerComponent("fullComponent", fullComponent);

      // 找到 controlBar 节点，添加控件
      this.player.getChild("controlBar").addChild("fullComponent");
    },

    // 点击播放暂停按钮触发事件
    handleClickBtn() {
      this.isPlay = !this.isPlay;
      if (this.isPlay) {
        this.player.play();
      } else {
        this.player.pause();
      }
      this.formatText();
    },

    // 全屏
    handleClickFull() {
      this.isFull = !this.isFull;
      console.info(this.isFull);
      if (this.isFull) {
        this.player.requestFullscreen();
      } else {
        this.player.exitFullscreen();
      }

      this.formatFull();
    },

    // 更换暂停播放icon
    formatText() {
      playCom.innerHTML = `<span>${this.isPlay ? "暂停" : "播放"}</span>`;
    },

    // 更换全屏icon
    formatFull() {
      fullCom.innerHTML = `<span>${this.isFull ? "还原" : "全屏"}</span>`;
    },

    // 获取总时长
    getVideoDuration() {
      this.player.on("loadedmetadata", () => {
        const totalTime = this.player.duration();
        this.totalTime = this.formatTime(totalTime);
      });
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose();
    }
  }
};
</script>
<style lang="scss">
.play_container {
  display: flex;
  justify-content: center;
  padding-bottom: 10px;
}

.video_container {
  width: 90%;
  height: 484px;
}

// 进度条
.vjs-progress-control {
  position: absolute !important;
  width: 100% !important;
  bottom: 52px;
  height: 1rem !important;

  .vjs-progress-holder {
    margin: 0 !important;
  }

  .vjs-slider-bar {
    background-color: #5fedf0 !important;
  }
}

.vjs-control-bar {
  height: 5rem !important;
  background-color: #1d345c !important;
  align-items: center;
}

// 自定义控件样式

.vjs-volume-panel {
  position: absolute !important;
  right: 45px;
  top: 15px;
}

.vjs-visible-text {
  margin: 0 10px !important;
}

.vjs-progress-text {
  margin-right: 120px !important;
}

.vjs-custom-btn {
  box-sizing: border-box !important;
  border-radius: 6px !important;
  height: 30px !important;
  background: rgba(49, 138, 194, 0.3) !important;
  letter-spacing: 1px;
}

.vjs-my-components {
  margin-left: 20px;
}

.vjs-full-components {
  position: absolute;
  right: 15px;
}

.vjs-play-progress {
  &::before {
    font-size: 0 !important;
  }
}

.video-js .vjs-control-bar {
  visibility: visible !important;
  opacity: 1 !important;
  transition: none !important;
}

video:focus {
  outline: -webkit-focus-ring-color auto 0px;
}

video {
  height: 470px !important;
}
</style>
